﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using HelixToolkit.Wpf;

namespace 数字孪生Demo.Model3D
{
    public class HouseModel3D : VisualObject3D
    {
        public GeometryModel3D roof = new GeometryModel3D();
        public GeometryModel3D wall = new GeometryModel3D();

        public HouseModel3D()
        {
            roof.Material = MaterialHelper.CreateMaterial(Colors.Brown, 0.5);
            wall.Material = MaterialHelper.CreateMaterial(Colors.LightGray, 0.5);

            InitModel();
            Model3DGroup group = new Model3DGroup();
            group.Children.Add(roof);
            group.Children.Add(wall);
            this.Visual3DModel = group;
        }

        private void InitModel()
        {
            double width = 10, height = 2.5, length = 20;
            double roof_angle = 15;
            double theta = roof_angle * Math.PI / 180;
            double y = height + height / 2 * Math.Tan(theta);

            // roof
            MeshBuilder roofBuilder = new MeshBuilder(false, false);
            var p0 = new Point(0, y);
            var p1 = new Point(width / 2 + 0.2 * Math.Cos(theta),height - 0.2 * Math.Sin(theta));
            var p2 = new Point(p1.X + 0.2 * Math.Sin(theta), p1.Y + 0.2 * Math.Cos(theta));
            var p3 = new Point(0,y + 0.2 / Math.Cos(theta));
            var p4 = new Point(-p2.X, p2.Y);
            var p5 = new Point(-p1.X,p1.Y);
            var roof_segment = new[] { p0,p1,p1,p2,p2,p3,p3,p4,p4,p5,p5,p0 };

            // 这里假设2D坐标系中的Y轴与局部坐标系中的Z轴对齐。
            // 通过提供的axisX向量（2D轮廓的X方向）和p1 - p0（挤出路径方向）计算局部坐标系的Y轴。
            // 然后通过X轴和Y轴的叉积（X × Y）来计算局部坐标系的Z轴方向，确定2D轮廓的“朝上”和“朝下”的方向。
            roofBuilder.AddExtrudedSegments(roof_segment, new Vector3D(0, -1, 0), new Point3D(-length / 2,0,0), new Point3D(length / 2,0,0));
            var cap = new[] { p0,p1,p2,p3,p4,p5 };
            roofBuilder.AddPolygon(cap, new Vector3D(0,-1,0), new Vector3D(0,0,1), new Point3D(-length / 2,0,0));
            roofBuilder.AddPolygon(cap, new Vector3D(0,1,0), new Vector3D(0, 0, 1), new Point3D(length / 2,0,0));

            roof.Geometry = roofBuilder.ToMesh(true);

            // wall 
            MeshBuilder wallBuilder = new MeshBuilder(false, false);
            wallBuilder.AddBox(new Point3D(0, 0, height / 2), length, width, height);
            var triangle = new[] { p0,new Point(width / 2,height),new Point(-width / 2,height) };
            wallBuilder.AddPolygon(triangle,new Vector3D(0,-1,0),new Vector3D(0,0,1),new Point3D(-length / 2,0,0));
            wallBuilder.AddPolygon(triangle,new Vector3D(0,1,0),new Vector3D(0,0,1),new Point3D(length / 2,0,0));
            wall.Geometry = wallBuilder.ToMesh(true);
        }

        public override void OnSelected(bool isSelected)
        {
            double opacity = isSelected ? 1.0 : 0.5;
            roof.Material = MaterialHelper.CreateMaterial(Colors.Brown, opacity);
            wall.Material = MaterialHelper.CreateMaterial(Colors.LightGray,opacity);
        }
    }
}
